<template>
  <div class="backtest-page">
    <!-- 页面锁定覆盖层 -->
    <div v-if="isPageLocked" class="page-lock-overlay">
      <div class="lock-content">
        <div class="spinner"></div>
        <div class="lock-text">
          <h3>计算进行中...</h3>
          <p>请勿切换页面，计算完成后将自动解锁</p>
          <div class="progress-bar">
            <div class="progress-fill" :style="{ width: calculationProgress + '%' }"></div>
          </div>
          <div class="progress-text">{{ calculationProgress }}%</div>
        </div>
      </div>
    </div>
    <div class="header">
      <h1>🤖 量化模型生成 & 实盘跟踪</h1>
      <p>选择股票组合，设置模型参数，生成预测模型，实时跟踪持仓</p>
    </div>

    <div class="main-content">
      <!-- 左侧：股票选择和参数设置 -->
      <div class="left-panel">
        <div class="section">
          <h3>🎯 股票选择</h3>
          <StockSelector @stocks-selected="onStocksSelected" />
          
          <div v-if="selectedStocks.length > 0" class="selected-stocks">
            <h4>已选择的股票 ({{ selectedStocks.length }}/15)</h4>
            <div class="stock-tags">
              <span 
                v-for="stock in selectedStocks" 
                :key="stock"
                class="stock-tag"
              >
                {{ stock.replace('.US', '') }}
              </span>
            </div>
          </div>
        </div>

        <div class="section">
          <h3>⚙️ 回测参数</h3>
          <div class="param-group">
            <label>回测日期:</label>
            <input 
              v-model="backtestParams.testDate" 
              type="date" 
              class="param-input"
            >
          </div>
          
          <div class="param-group">
            <label>初始资金:</label>
            <input 
              v-model="backtestParams.initialCapital" 
              type="number" 
              placeholder="100000"
              class="param-input"
            >
          </div>
          
          <div class="param-group">
            <label>交易策略:</label>
            <select v-model="backtestParams.strategy" class="param-input">
              <option value="equal_weight">等权重</option>
              <option value="momentum">动量策略</option>
              <option value="mean_reversion">均值回归</option>
              <option value="ml_prediction">机器学习预测</option>
            </select>
          </div>
          
          <div class="param-group">
            <label>再平衡频率:</label>
            <select v-model="backtestParams.rebalanceFreq" class="param-input">
              <option value="daily">每日</option>
              <option value="weekly">每周</option>
              <option value="monthly">每月</option>
              <option value="quarterly">每季度</option>
            </select>
          </div>
          
          <div class="model-info">
            <h4>📊 模型配置</h4>
            <div class="info-item">
              <span class="label">测试集:</span>
              <span class="value">{{ getTestPeriodText() }}</span>
            </div>
            <div class="info-item">
              <span class="label">训练集:</span>
              <span class="value">{{ getTrainPeriodText() }}</span>
            </div>
          </div>
        </div>

        <div class="section">
          <h3>🤖 生成模型</h3>
          <div class="button-group">
            <button 
              @click="runBacktest" 
              :disabled="!canRunBacktest"
              class="btn-primary"
              style="position: relative; z-index: 999;"
            >
              🧪 模型测试
            </button>
            <button 
              @click="clearResults" 
              :disabled="!hasResults"
              class="btn-secondary"
            >
              🗑️ 清空结果
            </button>
          </div>
        </div>
      </div>

      <!-- 右侧：回测结果和实盘跟踪 -->
      <div class="right-panel">
        <!-- 实盘跟踪组件 -->
        <GenerateBacktest 
          :selected-stocks="selectedStocks"
          :initial-capital="backtestParams.initialCapital"
          :backtest-results="backtestResults"
          :is-calculating="isCalculating"
          :calculation-progress="calculationProgress"
          @live-trading-started="onLiveTradingStarted"
          @live-trading-stopped="onLiveTradingStopped"
          @old-data-cleared="onOldDataCleared"
          @data-updated="onDataUpdated"
          @log-added="onLogAdded"
        />

        <!-- 回测结果 -->
        <div v-if="!hasResults" class="empty-state">
          <div class="empty-icon">🤖</div>
          <h3>准备生成模型</h3>
          <p>请选择股票并设置参数，然后点击"模型测试"</p>
        </div>

        <div v-else class="results-container">
          <!-- 回测结果摘要 -->
          <div v-if="backtestResults.backtest_results" class="backtest-summary-section">
            <div class="section-header">
              <h3>📊 回测结果摘要</h3>
            </div>
            <div class="summary-grid">
              <div class="summary-card">
                <div class="summary-title">初始资金</div>
                <div class="summary-value">${{ formatNumber(backtestResults.backtest_results.initial_capital || 0) }}</div>
              </div>
              <div class="summary-card">
                <div class="summary-title">最终资金</div>
                <div class="summary-value">${{ formatNumber(backtestResults.backtest_results.final_capital || 0) }}</div>
              </div>
              <div class="summary-card">
                <div class="summary-title">总收益率</div>
                <div class="summary-value" :class="getReturnClass(backtestResults.backtest_results.total_return || 0)">
                  {{ formatPercentage(backtestResults.backtest_results.total_return || 0) }}
                </div>
              </div>
              <div class="summary-card">
                <div class="summary-title">最大回撤</div>
                <div class="summary-value" :class="getReturnClass(-(backtestResults.backtest_results.max_drawdown || 0))">
                  {{ formatPercentage(backtestResults.backtest_results.max_drawdown || 0) }}
                </div>
              </div>
              <div class="summary-card">
                <div class="summary-title">夏普比率</div>
                <div class="summary-value">{{ (backtestResults.backtest_results.sharpe_ratio || 0).toFixed(3) }}</div>
              </div>
              <div class="summary-card">
                <div class="summary-title">交易次数</div>
                <div class="summary-value">{{ backtestResults.backtest_results.total_trades || 0 }}</div>
              </div>
            </div>
          </div>

          <!-- 特征选择和优化结果 -->
          <div v-if="backtestResults.optimizationResult || backtestResults.backtest_results?.optimization_result" class="optimization-section">
            <div class="section-header">
              <h3>🔍 特征选择与优化结果</h3>
              <div class="optimization-summary">
                <span class="summary-badge">
                  原始: {{ (backtestResults.optimizationResult?.summary?.original_count || backtestResults.backtest_results?.optimization_result?.summary?.original_count || 0) }} 只
                </span>
                <span class="summary-badge optimized">
                  优化后: {{ (backtestResults.optimizationResult?.summary?.optimized_count || backtestResults.backtest_results?.optimization_result?.summary?.optimized_count || 0) }} 只
                </span>
                <span class="summary-badge filtered">
                  筛选: {{ (backtestResults.optimizationResult?.summary?.filtered_count || backtestResults.backtest_results?.optimization_result?.summary?.filtered_count || 0) }} 只
                </span>
              </div>
            </div>

            <!-- 优化后的股票列表 -->
            <div class="optimized-stocks-section">
              <h4>✅ 优化后的股票列表</h4>
              <div class="optimized-stocks-grid">
                <div 
                  v-for="(stock, index) in (backtestResults.optimizationResult?.optimized_stocks_details || backtestResults.backtest_results?.optimization_result?.optimized_stocks_details || [])" 
                  :key="stock.symbol"
                  class="optimized-stock-card"
                >
                  <div class="stock-rank">#{{ index + 1 }}</div>
                  <div class="stock-symbol">{{ stock.symbol.replace('.US', '') }}</div>
                  <div class="stock-metrics">
                    <div class="metric">
                      <span class="label">重要性排名:</span>
                      <span class="value">{{ stock.importance_rank }}</span>
                    </div>
                    <div class="metric">
                      <span class="label">平均重要性:</span>
                      <span class="value">{{ formatNumber(stock.avg_importance) }}</span>
                    </div>
                    <div class="metric">
                      <span class="label">特征数量:</span>
                      <span class="value">{{ stock.feature_count }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 被筛选掉的股票 -->
            <div v-if="(backtestResults.optimizationResult?.filtering_reasons || backtestResults.backtest_results?.optimization_result?.filtering_reasons)" class="filtered-stocks-section">
              <h4>🗑️ 被筛选掉的股票及原因</h4>
              <div class="filtered-stocks-list">
                <div 
                  v-for="(reasons, symbol) in (backtestResults.optimizationResult?.filtering_reasons || backtestResults.backtest_results?.optimization_result?.filtering_reasons || {})" 
                  :key="symbol"
                  class="filtered-stock-item"
                >
                  <div class="stock-symbol">{{ symbol.replace('.US', '') }}</div>
                  <div class="filtering-reasons">
                    <span 
                      v-for="reason in reasons" 
                      :key="reason"
                      class="reason-tag"
                    >
                      {{ reason }}
                    </span>
                  </div>
                </div>
              </div>
            </div>

            <!-- 低影响股票 -->
            <div v-if="(backtestResults.optimizationResult?.low_impact_stocks || backtestResults.backtest_results?.optimization_result?.low_impact_stocks)" class="low-impact-section">
              <h4>⚠️ 低影响股票（特征重要性过低）</h4>
              <div class="low-impact-list">
                <div 
                  v-for="stock in (backtestResults.optimizationResult?.low_impact_stocks || backtestResults.backtest_results?.optimization_result?.low_impact_stocks || [])" 
                  :key="stock.symbol"
                  class="low-impact-item"
                >
                  <span class="stock-symbol">{{ stock.symbol.replace('.US', '') }}</span>
                  <span class="importance-value">
                    平均重要性: {{ formatNumber(stock.avg_importance) }} < {{ stock.threshold }}
                  </span>
                </div>
              </div>
            </div>

            <!-- 高相关性股票组 -->
            <div v-if="(backtestResults.optimizationResult?.high_correlation_groups || backtestResults.backtest_results?.optimization_result?.high_correlation_groups)" class="correlation-section">
              <h4>🔗 高相关性股票组</h4>
              <div class="correlation-groups">
                <div 
                  v-for="(group, index) in (backtestResults.optimizationResult?.high_correlation_groups || backtestResults.backtest_results?.optimization_result?.high_correlation_groups || [])" 
                  :key="index"
                  class="correlation-group"
                >
                  <div class="group-header">
                    <span class="group-title">组 {{ index + 1 }}</span>
                    <span class="group-correlation">相关性: {{ formatNumber(group.avg_correlation) }}</span>
                  </div>
                  <div class="group-stocks">
                    <span 
                      v-for="symbol in group.symbols" 
                      :key="symbol"
                      class="group-stock"
                    >
                      {{ symbol.replace('.US', '') }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div class="results-header">
            <h3>📊 模型测试结果</h3>
            <div class="result-summary">
              <div class="summary-item">
                <span class="label">总收益率</span>
                <span class="value" :class="getReturnClass(backtestResults.totalReturn)">
                  {{ formatPercentage(backtestResults.totalReturn) }}
                </span>
              </div>
              <div class="summary-item">
                <span class="label">年化收益率</span>
                <span class="value" :class="getReturnClass(backtestResults.annualReturn)">
                  {{ formatPercentage(backtestResults.annualReturn) }}
                </span>
              </div>
              <div class="summary-item">
                <span class="label">最大回撤</span>
                <span class="value negative">
                  {{ formatPercentage(backtestResults.maxDrawdown) }}
                </span>
              </div>
              <div class="summary-item">
                <span class="label">夏普比率</span>
                <span class="value" :class="getSharpeClass(backtestResults.sharpeRatio)">
                  {{ formatNumber(backtestResults.sharpeRatio) }}
                </span>
              </div>
            </div>
          </div>

          <div class="results-content">
            <div class="chart-section">
              <h4>📈 收益曲线</h4>
              <div class="chart-placeholder">
                <div class="chart-mock">
                  <div class="chart-line"></div>
                  <div class="chart-points">
                    <div class="point" v-for="i in 10" :key="i"></div>
                  </div>
                </div>
              </div>
            </div>

            <div class="metrics-section">
              <h4>📋 详细指标</h4>
              <div class="metrics-grid">
                <div class="metric-item">
                  <span class="metric-label">胜率</span>
                  <span class="metric-value">{{ formatPercentage(backtestResults.winRate) }}</span>
                </div>
                <div class="metric-item">
                  <span class="metric-label">交易次数</span>
                  <span class="metric-value">{{ backtestResults.tradeCount }}</span>
                </div>
                <div class="metric-item">
                  <span class="metric-label">平均持仓</span>
                  <span class="metric-value">{{ backtestResults.avgHolding }}天</span>
                </div>
                <div class="metric-item">
                  <span class="metric-label">波动率</span>
                  <span class="metric-value">{{ formatPercentage(backtestResults.volatility) }}</span>
                </div>
              </div>
            </div>

            <div class="portfolio-section">
              <h4>💼 投资组合</h4>
              <div class="portfolio-table">
                <div class="table-header">
                  <span>股票代码</span>
                  <span>权重</span>
                  <span>收益率</span>
                  <span>贡献度</span>
                </div>
                <div 
                  v-for="position in backtestResults.portfolio" 
                  :key="position.symbol"
                  class="table-row"
                >
                  <span class="symbol">{{ position.symbol }}</span>
                  <span class="weight">{{ formatPercentage(position.weight) }}</span>
                  <span class="return" :class="getReturnClass(position.return)">
                    {{ formatPercentage(position.return) }}
                  </span>
                  <span class="contribution" :class="getReturnClass(position.contribution)">
                    {{ formatPercentage(position.contribution) }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import StockSelector from '@/components/StockSelector.vue'
import GenerateBacktest from '@/views/GenerateBacktest.vue'

export default {
  name: 'Backtest',
  components: {
    StockSelector,
    GenerateBacktest
  },
  data() {
    return {
      selectedStocks: [],
      backtestParams: {
        testDate: this.getDefaultTestDate(),
        initialCapital: 100000,
        strategy: 'equal_weight',
        rebalanceFreq: 'monthly'
      },
      backtestResults: null,
      isRunning: false,
      isCalculating: false,
      calculationProgress: 0
    }
  },
  computed: {
    canRunBacktest() {
      const canRun = this.selectedStocks.length > 0 && !this.isRunning && !this.isCalculating
      console.log('canRunBacktest 计算:', {
        selectedStocksLength: this.selectedStocks.length,
        isRunning: this.isRunning,
        isCalculating: this.isCalculating,
        canRun: canRun
      })
      return canRun
    },
    hasResults() {
      return this.backtestResults !== null
    },
    isPageLocked() {
      const locked = this.isCalculating || this.isRunning
      console.log('🔒 页面锁定状态:', locked, { isCalculating: this.isCalculating, isRunning: this.isRunning })
      return locked
    }
  },
  mounted() {
    // 从localStorage恢复状态
    this.restoreState()
  },
  beforeUnmount() {
    // 保存状态到localStorage
    this.saveState()
  },
  methods: {
    // 获取默认测试日期（今天）
    getDefaultTestDate() {
      return new Date().toISOString().split('T')[0]
    },
    
    // 获取测试期间文本
    getTestPeriodText() {
      if (!this.backtestParams.testDate) return ''
      const testDate = new Date(this.backtestParams.testDate)
      const startDate = new Date(testDate)
      startDate.setMonth(startDate.getMonth() - 3)
      return `${startDate.toLocaleDateString()} - ${testDate.toLocaleDateString()}`
    },
    
    // 获取训练期间文本
    getTrainPeriodText() {
      if (!this.backtestParams.testDate) return ''
      const testDate = new Date(this.backtestParams.testDate)
      const trainStart = new Date(testDate)
      trainStart.setMonth(trainStart.getMonth() - 21) // 3个月 + 1.5年
      const trainEnd = new Date(testDate)
      trainEnd.setMonth(trainEnd.getMonth() - 3)
      return `${trainStart.toLocaleDateString()} - ${trainEnd.toLocaleDateString()}`
    },
    
    onStocksSelected(stocks) {
      this.selectedStocks = stocks
      console.log('选择的股票:', stocks)
      this.saveState() // 自动保存状态
    },
    
    async runBacktest() {
      console.log('🔍 模型测试按钮被点击了!')
      console.log('当前状态:', {
        selectedStocks: this.selectedStocks,
        canRunBacktest: this.canRunBacktest,
        isRunning: this.isRunning,
        isCalculating: this.isCalculating
      })
      
      if (!this.canRunBacktest) {
        console.log('❌ 无法运行回测，条件不满足')
        alert('无法运行回测，条件不满足')
        return
      }
      
      if (this.selectedStocks.length === 0) {
        console.log('❌ 请先选择股票')
        alert('请先选择股票')
        return
      }
      
      this.isRunning = true
      this.isCalculating = true
      this.calculationProgress = 0
      
      try {
        console.log('🚀 开始运行模型测试...')
        
        // 计算模型参数
        const testDate = new Date(this.backtestParams.testDate)
        const testStartDate = new Date(testDate)
        testStartDate.setMonth(testStartDate.getMonth() - 3)
        
        const trainStartDate = new Date(testStartDate)
        trainStartDate.setMonth(trainStartDate.getMonth() - 18) // 1.5年
        
        console.log('📊 模型参数:', {
          testStartDate: testStartDate.toISOString().split('T')[0],
          testEndDate: this.backtestParams.testDate,
          trainStartDate: trainStartDate.toISOString().split('T')[0],
          trainEndDate: testStartDate.toISOString().split('T')[0],
          selectedStocks: this.selectedStocks
        })
        
        // 调用后端API进行实际模型测试
        try {
          const response = await fetch('/api/model-test', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              stocks: this.selectedStocks,
              params: {
                // 回测参数
                testStartDate: testStartDate.toISOString().split('T')[0],
                testEndDate: this.backtestParams.testDate,
                trainStartDate: trainStartDate.toISOString().split('T')[0],
                trainEndDate: testStartDate.toISOString().split('T')[0],
                initialCapital: this.backtestParams.initialCapital,
                strategy: this.backtestParams.strategy,
                rebalanceFreq: this.backtestParams.rebalanceFreq,
                
                // 模型配置参数
                lookback_days: 60,
                max_positions: 10,
                max_position_size: 0.2,
                min_correlation: 0.6,
                train_test_split: 0.8,
                risk_free_rate: 0.02,
                transaction_cost: 0.001
              }
            })
          })
          
          if (!response.ok) {
            const errorText = await response.text()
            console.error('❌ HTTP错误:', response.status, errorText)
            throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`)
          }
          
          const result = await response.json()
          console.log('📊 后端响应:', result)
          
          if (result.success) {
            console.log('✅ 后端模型测试成功')
            console.log('📊 模型测试结果:', result.data)
            
            // 更新backtestResults，包含完整的模型测试结果
            this.backtestResults = {
              // 回测结果数据
              backtest_results: result.data.backtest_results,
              recommendations: result.data.recommendations,
              model1_results: result.data.model1_results,
              model2_results: result.data.model2_results,
              correlation_matrix: result.data.correlation_matrix,
              market_data_summary: result.data.market_data_summary,
              optimized_params: result.data.optimized_params,
              model_config: result.data.model_config,
              
              // 为了兼容性，也保留原有的直接属性
              ...result.data.backtest_results,
              optimizationResult: result.data.backtest_results?.optimization_result || null
            }
            
            console.log('📊 更新后的backtestResults:', this.backtestResults)
            
            // 触发GenerateBacktest组件的更新
            this.$nextTick(() => {
              // 通知GenerateBacktest组件数据已更新
              this.$emit('backtest-completed', this.backtestResults)
              this.saveState() // 自动保存状态
              console.log('✅ 计算完成，状态已更新')
            })
            
          } else {
            throw new Error(result.message || '模型测试失败')
          }
          
        } catch (apiError) {
          console.error('❌ 后端API调用失败:', apiError)
          console.error('❌ 错误详情:', {
            message: apiError.message,
            stack: apiError.stack,
            response: apiError.response
          })
          console.log('🔄 使用模拟数据作为备选方案')
          
          // 如果后端API调用失败，使用模拟数据
          await this.simulateModelTest({
            testStartDate: testStartDate.toISOString().split('T')[0],
            testEndDate: this.backtestParams.testDate,
            trainStartDate: trainStartDate.toISOString().split('T')[0],
            trainEndDate: testStartDate.toISOString().split('T')[0]
          })
        }
        
      } catch (error) {
        console.error('❌ 模型测试失败:', error)
        console.log(`模型测试失败: ${error.message || '未知错误'}`)
      } finally {
        this.isRunning = false
        this.isCalculating = false
        this.calculationProgress = 0
        console.log('🔄 计算状态已重置')
      }
    },
    
    async simulateModelTest(periods) {
      // 模拟模型测试计算过程
      const steps = 10
      for (let i = 0; i <= steps; i++) {
        this.calculationProgress = Math.round((i / steps) * 100)
        await new Promise(resolve => setTimeout(resolve, 200))
      }
      
      // 生成模拟的特征选择和优化结果
      const optimizationResult = this.generateMockOptimizationResult()
      
      // 生成模拟结果
      this.backtestResults = {
        totalReturn: 0.156,
        annualReturn: 0.182,
        maxDrawdown: -0.089,
        sharpeRatio: 1.24,
        winRate: 0.68,
        tradeCount: 24,
        avgHolding: 15,
        volatility: 0.142,
        testPeriod: periods,
        optimizationResult: optimizationResult,
        modelPredictions: this.selectedStocks.reduce((acc, stock) => {
          acc[stock.replace('.US', '')] = (Math.random() - 0.5) * 0.2
          return acc
        }, {}),
        portfolio: this.selectedStocks.map((stock, index) => ({
          symbol: stock.replace('.US', ''),
          weight: 1 / this.selectedStocks.length,
          return: (Math.random() - 0.5) * 0.4,
          contribution: (Math.random() - 0.5) * 0.2
        }))
      }
    },
    
    generateMockOptimizationResult() {
      // 生成模拟的特征选择和优化结果
      const originalCount = this.selectedStocks.length
      const optimizedCount = Math.floor(originalCount * 0.7) // 保留70%
      const filteredCount = originalCount - optimizedCount
      
      // 按重要性排序股票
      const sortedStocks = [...this.selectedStocks].sort(() => Math.random() - 0.5)
      const optimizedStocks = sortedStocks.slice(0, optimizedCount)
      const filteredStocks = sortedStocks.slice(optimizedCount)
      
      // 生成优化后的股票详情
      const optimizedStocksDetails = {}
      optimizedStocks.forEach((stock, index) => {
        optimizedStocksDetails[stock] = {
          importance_rank: index + 1,
          avg_importance: 0.1 + Math.random() * 0.2,
          feature_count: 6
        }
      })
      
      // 生成被筛选掉的股票原因
      const filteringReasons = {}
      filteredStocks.forEach(stock => {
        const reasons = []
        if (Math.random() > 0.7) {
          reasons.push('特征重要性过低')
        }
        if (Math.random() > 0.8) {
          reasons.push('高相关性组中被替代')
        }
        if (Math.random() > 0.9) {
          reasons.push('综合评分较低')
        }
        if (reasons.length === 0) {
          reasons.push('综合评分较低')
        }
        filteringReasons[stock] = reasons
      })
      
      // 生成低影响股票
      const lowImpactStocks = filteredStocks.slice(0, Math.floor(filteredStocks.length * 0.3)).map(stock => ({
        symbol: stock,
        avg_importance: 0.05 + Math.random() * 0.05,
        threshold: 0.1,
        reason: '特征重要性过低'
      }))
      
      // 生成高相关性组
      const highCorrelationGroups = []
      if (filteredStocks.length > 2) {
        const group1 = filteredStocks.slice(0, 2)
        highCorrelationGroups.push({
          symbols: group1,
          avg_correlation: 0.85 + Math.random() * 0.1,
          size: group1.length,
          reason: '高相关性组'
        })
      }
      
      return {
        summary: {
          original_count: originalCount,
          optimized_count: optimizedCount,
          filtered_count: filteredCount,
          filtering_ratio: (filteredCount / originalCount) * 100
        },
        optimized_stocks_details: optimizedStocksDetails,
        filtering_reasons: filteringReasons,
        low_impact_stocks: lowImpactStocks,
        high_correlation_groups: highCorrelationGroups
      }
    },
    
    clearResults() {
      this.backtestResults = null
      console.log('已清除模型测试结果')
      this.saveState() // 自动保存状态
    },
    
    // 实盘跟踪事件处理
    onLiveTradingStarted() {
      console.log('实盘跟踪已开始')
    },
    
    onLiveTradingStopped() {
      console.log('实盘跟踪已停止')
    },
    
    onOldDataCleared() {
      // 清除模型测试结果
      this.backtestResults = null
      console.log('旧数据已清除')
    },
    
    onDataUpdated(portfolio) {
      console.log('实盘数据已更新:', portfolio)
    },
    
    onLogAdded(log) {
      console.log('新交易日志:', log)
    },
    
    formatPercentage(value) {
      return `${(value * 100).toFixed(2)}%`
    },
    
    formatNumber(value) {
      return value.toFixed(2)
    },
    
    getReturnClass(value) {
      return value >= 0 ? 'positive' : 'negative'
    },
    
    getSharpeClass(value) {
      if (value >= 1.0) return 'positive'
      if (value >= 0.5) return 'neutral'
      return 'negative'
    },

    testButtonClick() {
      console.log('🧪 模型测试按钮被点击了!')
      
      // 检查条件
      if (this.selectedStocks.length === 0) {
        console.log('❌ 请先选择股票')
        return
      }
      
      // 如果条件满足，调用原来的方法
      this.runBacktest()
    },
    
    saveState() {
      // 保存状态到localStorage
      const state = {
        selectedStocks: this.selectedStocks,
        backtestParams: this.backtestParams,
        backtestResults: this.backtestResults,
        isRunning: this.isRunning,
        isCalculating: this.isCalculating,
        calculationProgress: this.calculationProgress
      }
      localStorage.setItem('backtestState', JSON.stringify(state))
      console.log('💾 状态已保存到localStorage')
    },
    
    restoreState() {
      // 从localStorage恢复状态
      try {
        const savedState = localStorage.getItem('backtestState')
        if (savedState) {
          const state = JSON.parse(savedState)
          
          // 恢复状态，但跳过计算中的状态
          if (!state.isCalculating && !state.isRunning) {
            this.selectedStocks = state.selectedStocks || []
            this.backtestParams = state.backtestParams || this.backtestParams
            this.backtestResults = state.backtestResults || null
            console.log('🔄 状态已从localStorage恢复')
          } else {
            console.log('⚠️ 跳过恢复计算中的状态')
          }
        }
      } catch (error) {
        console.error('❌ 恢复状态失败:', error)
      }
    }
  }
}
</script>

<style scoped>
.backtest-page {
  min-height: 100vh;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 20px;
  position: relative;
}

/* 页面锁定覆盖层 */
.page-lock-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  backdrop-filter: blur(4px);
}

.lock-content {
  background: white;
  border-radius: 16px;
  padding: 40px;
  text-align: center;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
  max-width: 400px;
  width: 90%;
}

.spinner {
  width: 60px;
  height: 60px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #667eea;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 20px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.lock-text h3 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 20px;
  font-weight: 600;
}

.lock-text p {
  margin: 0 0 20px 0;
  color: #666;
  font-size: 14px;
}

.progress-bar {
  width: 100%;
  height: 8px;
  background: #f0f0f0;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 10px;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #667eea, #764ba2);
  border-radius: 4px;
  transition: width 0.3s ease;
}

.progress-text {
  font-size: 16px;
  font-weight: 600;
  color: #667eea;
}

.header {
  text-align: center;
  margin-bottom: 30px;
  color: #333;
}

.header h1 {
  margin: 0 0 10px 0;
  font-size: 32px;
  font-weight: 700;
}

.header p {
  margin: 0;
  color: #666;
  font-size: 16px;
}

.main-content {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 30px;
  max-width: 1400px;
  margin: 0 auto;
}

.left-panel {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.section h3 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.selected-stocks {
  margin-top: 16px;
}

.selected-stocks h4 {
  margin: 0 0 12px 0;
  color: #666;
  font-size: 14px;
  font-weight: 500;
}

.stock-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.stock-tag {
  background: #667eea;
  color: white;
  padding: 6px 12px;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 500;
}

.param-group {
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.param-group label {
  min-width: 80px;
  color: #555;
  font-size: 14px;
  font-weight: 500;
  flex-shrink: 0;
}

.param-input {
  width: 100%;
  padding: 10px 12px;
  border: 2px solid #e1e5e9;
  border-radius: 8px;
  font-size: 14px;
  transition: all 0.3s ease;
}

.param-input[type="date"] {
  width: 140px;
  min-width: 140px;
  flex-shrink: 0;
}

.param-input[type="number"] {
  width: 120px;
  min-width: 120px;
  flex-shrink: 0;
}

.param-input[type="select"], select.param-input {
  width: 160px;
  min-width: 160px;
  flex-shrink: 0;
}

.param-input:focus {
  outline: none;
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}

.model-info {
  margin-top: 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
  border-left: 4px solid #667eea;
}

.model-info h4 {
  margin: 0 0 12px 0;
  color: #333;
  font-size: 14px;
  font-weight: 600;
}

.info-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 12px;
}

.info-item:last-child {
  margin-bottom: 0;
}

.info-item .label {
  color: #666;
  font-weight: 500;
}

.info-item .value {
  color: #333;
  font-weight: 600;
}

.button-group {
  display: flex;
  gap: 12px;
}

.btn-primary, .btn-secondary {
  flex: 1;
  padding: 12px 20px;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
  position: relative;
  z-index: 101;
  pointer-events: auto;
}

.btn-primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn-secondary {
  background: #f8f9fa;
  color: #666;
  border: 1px solid #ddd;
}

.btn-secondary:hover:not(:disabled) {
  background: #e9ecef;
  border-color: #adb5bd;
}

.btn-secondary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.right-panel {
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 400px;
  color: #999;
  text-align: center;
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 16px;
}

.empty-state h3 {
  margin: 0 0 8px 0;
  color: #666;
}

.empty-state p {
  margin: 0;
  color: #999;
}

.results-container {
  height: 100%;
}

/* 回测结果摘要 */
.backtest-summary-section {
  margin-bottom: 24px;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.summary-card {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
}

.summary-title {
  font-size: 12px;
  color: #666;
  margin-bottom: 8px;
  font-weight: 500;
}

.summary-value {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.results-header {
  padding: 24px;
  border-bottom: 1px solid #eee;
  background: #f8f9fa;
}

.results-header h3 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 20px;
  font-weight: 600;
}

.result-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

.summary-item {
  text-align: center;
}

.summary-item .label {
  display: block;
  font-size: 12px;
  color: #666;
  margin-bottom: 4px;
}

.summary-item .value {
  display: block;
  font-size: 18px;
  font-weight: 600;
}

.value.positive {
  color: #28a745;
}

.value.negative {
  color: #dc3545;
}

.value.neutral {
  color: #6c757d;
}

.results-content {
  padding: 24px;
}

.chart-section, .metrics-section, .portfolio-section {
  margin-bottom: 32px;
}

.chart-section h4, .metrics-section h4, .portfolio-section h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.chart-placeholder {
  height: 200px;
  background: #f8f9fa;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-mock {
  position: relative;
  width: 100%;
  height: 100px;
}

.chart-line {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, #667eea, #764ba2);
  border-radius: 1px;
}

.chart-points {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.point {
  width: 8px;
  height: 8px;
  background: #667eea;
  border-radius: 50%;
  transform: translateY(-50%);
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.metric-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #f8f9fa;
  border-radius: 8px;
}

.metric-label {
  color: #666;
  font-size: 14px;
}

.metric-value {
  font-weight: 600;
  color: #333;
}

.portfolio-table {
  border: 1px solid #eee;
  border-radius: 8px;
  overflow: hidden;
}

.table-header {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  background: #f8f9fa;
  padding: 12px 16px;
  font-weight: 600;
  color: #333;
  font-size: 14px;
}

.table-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  padding: 12px 16px;
  border-bottom: 1px solid #eee;
  font-size: 14px;
}

/* 特征选择和优化结果样式 */
.optimization-section {
  padding: 24px;
  border-bottom: 1px solid #eee;
  background: #f8f9fa;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.section-header h3 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.optimization-summary {
  display: flex;
  gap: 12px;
}

.summary-badge {
  padding: 6px 12px;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 600;
  background: #e9ecef;
  color: #6c757d;
}

.summary-badge.optimized {
  background: #d4edda;
  color: #155724;
}

.summary-badge.filtered {
  background: #f8d7da;
  color: #721c24;
}

.optimized-stocks-section,
.filtered-stocks-section,
.low-impact-section,
.correlation-section {
  margin-bottom: 24px;
}

.optimized-stocks-section h4,
.filtered-stocks-section h4,
.low-impact-section h4,
.correlation-section h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.optimized-stocks-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.optimized-stock-card {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 16px;
  position: relative;
}

.stock-rank {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  background: #007bff;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
}

.stock-symbol {
  font-weight: 600;
  color: #333;
  margin-bottom: 12px;
  font-size: 16px;
}

.stock-metrics {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.metric {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
}

.metric .label {
  color: #666;
}

.metric .value {
  font-weight: 600;
  color: #333;
}

.filtered-stocks-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.filtered-stock-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
}

.filtering-reasons {
  display: flex;
  gap: 8px;
}

.reason-tag {
  padding: 4px 8px;
  background: #f8d7da;
  color: #721c24;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}

.low-impact-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.low-impact-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: white;
  border: 1px solid #fff3cd;
  border-radius: 6px;
  font-size: 14px;
}

.low-impact-item .stock-symbol {
  font-weight: 600;
  color: #333;
  margin: 0;
}

.importance-value {
  color: #856404;
  font-size: 12px;
}

.correlation-groups {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.correlation-group {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 16px;
}

.group-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.group-title {
  font-weight: 600;
  color: #333;
}

.group-correlation {
  font-size: 12px;
  color: #666;
}

.group-stocks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.group-stock {
  padding: 4px 8px;
  background: #e9ecef;
  color: #495057;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.table-row:last-child {
  border-bottom: none;
}

.table-row:hover {
  background: #f8f9fa;
}

.symbol {
  font-weight: 600;
  color: #333;
}

.weight, .return, .contribution {
  text-align: right;
}

@media (max-width: 1024px) {
  .main-content {
    grid-template-columns: 1fr;
  }
  
  .result-summary {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .metrics-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .backtest-page {
    padding: 10px;
  }
  
  .header h1 {
    font-size: 24px;
  }
  
  .section {
    padding: 16px;
  }
  
  .button-group {
    flex-direction: column;
  }
  
  .param-group {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .param-group label {
    min-width: auto;
  }
  
  .param-input[type="date"],
  .param-input[type="number"],
  .param-input[type="select"],
  select.param-input {
    width: 100%;
    min-width: auto;
  }
  
  .table-header, .table-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
  
  .weight, .return, .contribution {
    text-align: left;
  }
}
</style> 